Skip to content

Conversation

@maltelenz
Copy link
Contributor

These originate from figures created for Wolfram System Modeler, and are likely to need cleanup and improvement.

Our one existing figure in MSL is probably a good style to follow:

figures = {
Figure(
title = "Anti-windup compensation",
identifier = "anti-windup",
preferred = true,
plots = {
Plot(
title = "Reference tracking",
identifier = "tracking",
curves = {
Curve(y = integrator.y, legend = "Reference speed"),
Curve(y = inertia1.w, legend = "Actual speed")}),
Plot(
title = "Anti-windup limiter",
identifier = "limiter",
curves = {
Curve(y = PI.limiter.u, legend = "Input to the anti-windup limiter"),
Curve(y = PI.y, legend = "Controller output")})},
caption = "%(plot:tracking) Reference speed (%(variable:integrator.y)) and the actual speed (%(variable:inertia1.w)). The system initializes in steady state, since no transients are present. The inertia follows the reference speed quite good until the end of the constant speed phase. Then there is a deviation.
%(plot:limiter) Here the reason for the deviation can be seen: The output of the controller (%(variable:PI.y)) is in its limits. The anti-windup compensation works reasonably, since the input to the limiter (%(variable:PI.limiter.u)) is forced back to its limit after a transient phase.
")}));

Creating as Draft to indicate that library officer(s) probably want/should improve them before merging.

These originate from figures created for Wolfram System Modeler, and are likely to need cleanup and improvement.
@maltelenz maltelenz requested a review from HansOlsson July 16, 2025 10:13
@maltelenz maltelenz added the figures Related to figures/plots label Jul 16, 2025
@beutlich beutlich added example Issue only addresses example(s) L: StateGraph Issue addresses Modelica.StateGraph labels Jul 25, 2025
Copy link
Contributor

@HansOlsson HansOlsson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They seem good, except for ShowCompositeStep that seems overloaded with information.
(8 different curves in one of several sub-plots!)

To me it makes sense that the default figure doesn't show everything - and if someone wants to understand the composite-step open up a different figure.

  • I'm also unsure if "Output from initialStep" is a good description for initialStep.active, (as there's also outPort) would "Active initialStep" be clearer (and also shorther)?
  • I notice that plotting wait-time together with active only works when wait-time is about 1s - so we might need to re-consider for different models, but it works for these.
  • There's a bit of tendency of information overload in ShowExceptions as well, but I think it works.

@HansOlsson
Copy link
Contributor

Oh, and adding more textual description in the figures (as in the linked one) would also be good.

@henrikt-ma
Copy link
Contributor

@HansOlsson, your input is appreciated. Now we just need the library officer(s) to step in and propose or make the concrete changes. From the Wolfram side, we can use our experience with figures in general to confirm that proposed changes look sensible, but we are not the domain experts who would know best which variables to include in the plots, or what to write in the captions.

@HansOlsson
Copy link
Contributor

@HansOlsson, your input is appreciated. Now we just need the library officer(s) to step in and propose or make the concrete changes. From the Wolfram side, we can use our experience with figures in general to confirm that proposed changes look sensible, but we are not the domain experts who would know best which variables to include in the plots, or what to write in the captions.

Hmm... Checking for Modelica.StateGraph, it's @HansOlsson and @MartinOtter !
I'll try formulate some caption at least for the FirstExample(s) as a first step.

@henrikt-ma
Copy link
Contributor

Hmm... Checking for Modelica.StateGraph, it's @HansOlsson and @MartinOtter !
I'll try formulate some caption at least for the FirstExample(s) as a first step.

Great! In my opinion, having a caption should be a base requirement that all figures should live up to before a PR like this is accepted. How about writing down this sort of rule in https://github.com/modelica/ModelicaStandardLibrary/blob/master/Modelica/UsersGuide/Conventions.mo? With guidelines to follow, it should be easier to recognize when these PRs with the first round of figures are ready to be merged, and we would get more consistent looks across sub-libraries.

Comment on lines +1154 to +1192
figures = {
Figure(
title = "Boolean signal in system",
identifier = "22111",
preferred = true,
plots = {
Plot(
curves = {
Curve(y = step0.active, legend = "Output from step0"),
Curve(y = transition1.t, legend = "transition1 wait time")
}
),
Plot(
curves = {
Curve(y = step1.active, legend = "Output from step1")
}
),
Plot(
curves = {
Curve(y = compositeStep.active, legend = "Output from entire compositeStep block = sum of initStep, step3, and exitStep"),
Curve(y = compositeStep.initStep.active, legend = "Output from initStep"),
Curve(y = compositeStep.step3.active, legend = "Output from step3"),
Curve(y = compositeStep.exitStep.active, legend = "Output from exitStep"),
Curve(y = compositeStep.transition3.t, legend = "transistion3 wait time"),
Curve(y = compositeStep.transition5.t, legend = "transition5 wait time"),
Curve(y = compositeStep.transition5.waitTime, legend = "transition5 target wait time"),
Curve(y = transition2.t, legend = "transition2 wait time")
}
),
Plot(
curves = {
Curve(y = step6.active, legend = "Output from step6"),
Curve(y = transition7.condition, legend = "transition7 condition for firing status")
}
)
}
)
}
), experiment(StopTime=15));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
figures = {
Figure(
title = "Boolean signal in system",
identifier = "22111",
preferred = true,
plots = {
Plot(
curves = {
Curve(y = step0.active, legend = "Output from step0"),
Curve(y = transition1.t, legend = "transition1 wait time")
}
),
Plot(
curves = {
Curve(y = step1.active, legend = "Output from step1")
}
),
Plot(
curves = {
Curve(y = compositeStep.active, legend = "Output from entire compositeStep block = sum of initStep, step3, and exitStep"),
Curve(y = compositeStep.initStep.active, legend = "Output from initStep"),
Curve(y = compositeStep.step3.active, legend = "Output from step3"),
Curve(y = compositeStep.exitStep.active, legend = "Output from exitStep"),
Curve(y = compositeStep.transition3.t, legend = "transistion3 wait time"),
Curve(y = compositeStep.transition5.t, legend = "transition5 wait time"),
Curve(y = compositeStep.transition5.waitTime, legend = "transition5 target wait time"),
Curve(y = transition2.t, legend = "transition2 wait time")
}
),
Plot(
curves = {
Curve(y = step6.active, legend = "Output from step6"),
Curve(y = transition7.condition, legend = "transition7 condition for firing status")
}
)
}
)
}
), experiment(StopTime=15));
figures = {
Figure(
title = "Cyclic activation of a parallel and alternative steps.",
caption="This shows that steps can be in parallel (synchronized at the end).\nAdditionally it contains alternatives, that are selected based on priority.\nThe compositeStep shows how to build structure"
identifier = "22111",
preferred = true,
plots = {
Plot(
curves = {
Curve(y = step0.active, legend = "Active step0"),
Curve(y = compositeStep.active, legend = "Active compositeStep - parallel to step1"),
Curve(y = step1.active, legend = "Active step1"),
Curve(y = step6.active, legend = "Active step6")}),
Plot(
curves={
Curve(y = compositeStep.active, legend = "Active compositeStep - where step3, step4, step4a are alternatives"),
Curve(y = compositeStep.initStep.active, legend = "Active compositeStep.initStep"),
Curve(y = compositeStep.step3.active, legend = "Active compositeStep.step3"),
Curve(y = compositeStep.step4.active, legend = "Active compositeStep.step4"),
Curve(y = compositeStep.step4a.active, legend = "Active compositeStep.step4a"),
Curve(y = compositeStep.exitStep.active, legend = "Active compositeStep.exitStep")
}
)
}
)
}
),
experiment(StopTime=15));

As I understand it, this illustrates the main point of the example as:

  • step1 and compositeStep are in parallel; so both are active at the same time (there's a synchronization when ending)
  • inside compositeStep there are alternatives (step3, step4, step4a) - where only one is active.

The actual timings etc aren't the focus, so don't plot them.
(Should have a similar figure for ExecutionPaths.)

I believe the example would be clearer if different alternatives were selected for the different cycles.

Comment on lines +812 to +836
annotation (
Documentation(
figures = {
Figure(
title = "Boolean signal in system",
identifier = "ef029",
preferred = true,
plots = {
Plot(
curves = {
Curve(y = initialStep.active, legend = "Output from initialStep"),
Curve(y = transition1.t, legend = "transition1 wait time")
}
),
Plot(
curves = {
Curve(y = step.active, legend = "Output from step"),
Curve(y = transition2.t, legend = "transition2 wait time")
}
)
}
)
}
),
experiment(StopTime=5.5));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
annotation (
Documentation(
figures = {
Figure(
title = "Boolean signal in system",
identifier = "ef029",
preferred = true,
plots = {
Plot(
curves = {
Curve(y = initialStep.active, legend = "Output from initialStep"),
Curve(y = transition1.t, legend = "transition1 wait time")
}
),
Plot(
curves = {
Curve(y = step.active, legend = "Output from step"),
Curve(y = transition2.t, legend = "transition2 wait time")
}
)
}
)
}
),
experiment(StopTime=5.5));
annotation (
Documentation(
figures = {
Figure(
title = "Cyclic activation of the states",
identifier = "ef029",
preferred = true,
caption="Shows how the system cycles from initialStep to Step, and then repeated.\nThe time before transition is determined by the waitTime (1s) of the transitions.",
plots = {
Plot(
curves = {
Curve(y = initialStep.active, legend = "Active initialStep"),
Curve(y = step.active, legend = "Active step")}),
Plot(
curves = {
Curve(y = transition1.t, legend = "transition1 time waiting"),
Curve(y = transition2.waitTime, legend = "transition1 waitTime parameter")})})}),
experiment(StopTime=5.5));

After some thinking I would prefer to re-order, and re-name the plots like that, except I'm not happy with the "waitTime parameter" part.

The reasons are:

  • Having activations in one plot may make it clearer that just one state is active.
  • Calling it "Active initialStep" was as indicated clearer to me
  • Given that there is a parameter "waitTime" (the time until transition triggers) plotting another variable as "wait time" was a bit confusing to me, so I renamed it to "time waiting".
  • One could add another sub-plot for transition2, but I don't think it is needed.

At first I had the existing two transition*.t in one plot - but it was harder to understand for me - especially if one plotted waitTime as well.

@HansOlsson
Copy link
Contributor

I didn't update the plots for Modelica.StateGraph.Examples.ShowExceptions yet, as I think it needs improvement.

@HansOlsson
Copy link
Contributor

I would propose to not add a figure for ShowExceptions at the current state, but instead add it together with the other improvements of that example - and then make sure that the Figure is actually understandable; see #4722

Note that the original figures were sort of ok, but they didn't really illustrate the examples that well, partially since the models don't do a good job of that either. I don't know why no-one have noticed earlier, but it seems that adding figures helps in several ways.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

example Issue only addresses example(s) figures Related to figures/plots L: StateGraph Issue addresses Modelica.StateGraph

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants